package com.zhou.common.operator.log.storage;

import com.zhou.common.operator.log.core.OperateLogProperty;
import com.zhou.common.operator.log.core.ao.OperateLogInfoGetPageListAO;
import com.zhou.common.operator.log.core.model.ClientInfo;
import com.zhou.common.operator.log.core.model.OperateLogInfo;
import com.zhou.common.operator.log.core.model.PayloadInfo;
import com.zhou.common.operator.log.core.model.PrincipalInfo;
import com.zhou.common.operator.log.core.service.impl.AbstractStorageService;
import com.zhou.common.pub.model.CommonPage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

import javax.annotation.PostConstruct;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.List;

public class JdbcStorageService extends AbstractStorageService {
    private static final String TABLE_NAME = "operate_history";
    private String insertSql = null;
    private JdbcTemplate jdbcTemplate;

    public JdbcStorageService(OperateLogProperty property, JdbcTemplate jdbcTemplate) {
        super(property);
        this.jdbcTemplate = jdbcTemplate;
    }

    @PostConstruct
    public void init() {
        this.insertSql = "insert into " + this.getTableName() + "(action, resource,business_id, user_id, user_name, org_id, org_name, browser, browser_version, os, client_ip, server_ip, remark, add_time, operating_system,operating_instruction,operating_type,operating_module,user_phone,mac_address)  values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);";
    }

    @Override
    protected void saveBatch(final List<OperateLogInfo> logs) {
        try {
            this.jdbcTemplate.batchUpdate(this.insertSql, new BatchPreparedStatementSetter() {
                @Override
                public void setValues(PreparedStatement preparedStatement, int i) throws SQLException {
                    OperateLogInfo item = (OperateLogInfo) logs.get(i);
                    PayloadInfo payloadInfo = item.getPayloadInfo();
                    String businessId = payloadInfo != null ? payloadInfo.getBusinessId() : null;
                    preparedStatement.setString(1, JdbcStorageService.this.defaultString(item.getAction()));
                    preparedStatement.setString(2, JdbcStorageService.this.defaultString(item.getResource()));
                    preparedStatement.setString(3, JdbcStorageService.this.defaultString(businessId));
                    preparedStatement.setString(4, JdbcStorageService.this.defaultString(item.getPrincipal().getUserId()));
                    preparedStatement.setString(5, JdbcStorageService.this.defaultString(item.getPrincipal().getUserName()));
                    preparedStatement.setString(6, JdbcStorageService.this.defaultString(item.getPrincipal().getOrgId()));
                    preparedStatement.setString(7, JdbcStorageService.this.defaultString(item.getPrincipal().getOrgName()));
                    preparedStatement.setString(8, JdbcStorageService.this.defaultString(item.getClientInfo().getBrowser()));
                    preparedStatement.setString(9, JdbcStorageService.this.defaultString(item.getClientInfo().getBrowserVersion()));
                    preparedStatement.setString(10, JdbcStorageService.this.defaultString(item.getClientInfo().getOs()));
                    preparedStatement.setString(11, JdbcStorageService.this.defaultString(item.getClientInfo().getClientIp()));
                    preparedStatement.setString(12, JdbcStorageService.this.defaultString(item.getClientInfo().getServerIp()));
                    preparedStatement.setString(13, JdbcStorageService.this.defaultString(item.getRemark()));
                    preparedStatement.setTimestamp(14, new Timestamp(item.getAddTime().getTime()));
                    preparedStatement.setString(15, JdbcStorageService.this.defaultString(item.getOperatingSystem()));
                    preparedStatement.setString(16, JdbcStorageService.this.defaultString(item.getOperatingInstruction()));
                    preparedStatement.setString(17, JdbcStorageService.this.defaultString(item.getOperatingType()));
                    preparedStatement.setString(18, JdbcStorageService.this.defaultString(item.getOperatingModule()));
                    preparedStatement.setString(19, JdbcStorageService.this.defaultString(item.getPrincipal().getUserPhone()));
                    preparedStatement.setString(20, JdbcStorageService.this.defaultString(item.getClientInfo().getMacAddress()));
                }

                @Override
                public int getBatchSize() {
                    return logs.size();
                }
            });
        } catch (Exception var3) {
            var3.printStackTrace();
        }

    }

    private String getTableName() {
        return StringUtils.defaultString(this.getProperties().getTableName(), "operate_history");
    }

    private String defaultString(String input) {
        return StringUtils.defaultString(input, "");
    }

    @Override
    public CommonPage<OperateLogInfo> getPageList(OperateLogInfoGetPageListAO ao) {
        StringBuilder sql = new StringBuilder();
        sql.append("select id ,action, resource,business_id, user_id, user_name, org_id, org_name, browser, browser_version, os, client_ip, server_ip, remark, add_time, operating_system, operating_instruction, operating_system, operating_type, operating_module, user_phone, mac_address from `" + this.getTableName() + "` where 1=1");
        if (!com.mysql.cj.util.StringUtils.isNullOrEmpty(ao.getUserName())) {
            sql.append(" and user_name like concat('%','").append(ao.getUserName()).append("','%') ");
        }

        if (!com.mysql.cj.util.StringUtils.isNullOrEmpty(ao.getResource())) {
            sql.append(" and resource like concat('%','").append(ao.getResource()).append("','%') ");
        }

        if (!com.mysql.cj.util.StringUtils.isNullOrEmpty(ao.getUserPhone())) {
            sql.append(" and user_phone like concat('%','").append(ao.getUserPhone()).append("','%') ");
        }

        if (!com.mysql.cj.util.StringUtils.isNullOrEmpty(ao.getOperatingSystem())) {
            sql.append(" and operating_system = '").append(ao.getOperatingSystem()).append("'");
        }

        if (!com.mysql.cj.util.StringUtils.isNullOrEmpty(ao.getOperatingType())) {
            sql.append(" and operating_module = '").append(ao.getOperatingType()).append("'");
        }

        if (!com.mysql.cj.util.StringUtils.isNullOrEmpty(ao.getOperatingModule())) {
            sql.append(" and operating_type = '").append(ao.getOperatingModule()).append("'");
        }

        if (!com.mysql.cj.util.StringUtils.isNullOrEmpty(ao.getClientIp())) {
            sql.append(" and client_ip like concat('%','").append(ao.getClientIp()).append("','%') ");
        }

        if (!com.mysql.cj.util.StringUtils.isNullOrEmpty(ao.getMacAddress())) {
            sql.append(" and mac_address like concat('%','").append(ao.getMacAddress()).append("','%') ");
        }

        if (!com.mysql.cj.util.StringUtils.isNullOrEmpty(ao.getOperTimeStart()) && !com.mysql.cj.util.StringUtils.isNullOrEmpty(ao.getOperTimeEnd())) {
            sql.append(" and add_time between '").append(ao.getOperTimeStart()).append("' and '").append(ao.getOperTimeEnd()).append("' ");
        }

        int total;
        if (ao.getPageNo() != null && ao.getPageSize() != null) {
            int start = (ao.getPageNo() - 1) * ao.getPageSize();
            total = ao.getPageSize();
            sql.append(" limit " + start + "," + total);
        }

        List<OperateLogInfo> list = this.jdbcTemplate.query(sql.toString(), new RowMapper<OperateLogInfo>() {
            @Override
            public OperateLogInfo mapRow(ResultSet resultSet, int i) throws SQLException {
                OperateLogInfo operateLogInfo = new OperateLogInfo();
                ClientInfo clientInfo = new ClientInfo();
                clientInfo.setClientIp(resultSet.getString("client_ip"));
                clientInfo.setBrowser(resultSet.getString("browser"));
                clientInfo.setBrowserVersion(resultSet.getString("browser_version"));
                clientInfo.setServerIp(resultSet.getString("client_ip"));
                clientInfo.setOs(resultSet.getString("os"));
                operateLogInfo.setClientInfo(clientInfo);
                PayloadInfo payloadInfo = new PayloadInfo();
                payloadInfo.setBusinessId(resultSet.getString("business_id"));
                operateLogInfo.setPayloadInfo(payloadInfo);
                PrincipalInfo principalInfo = new PrincipalInfo();
                principalInfo.setOrgId(resultSet.getString("org_id"));
                principalInfo.setOrgName(resultSet.getString("org_name"));
                principalInfo.setUserName(resultSet.getString("user_name"));
                principalInfo.setUserId(resultSet.getString("user_id"));
                operateLogInfo.setPrincipal(principalInfo);
                operateLogInfo.setAction(resultSet.getString("action"));
                operateLogInfo.setResource(resultSet.getString("resource"));
                operateLogInfo.setAddTime(resultSet.getDate("add_time"));
                operateLogInfo.setRemark(resultSet.getString("remark"));
                operateLogInfo.setId(resultSet.getLong("id"));
                return operateLogInfo;
            }
        });
        total = 0;
        if (this.getTotal(ao) != null) {
            total = this.getTotal(ao);
        }

        int totalPage;
        if (total % ao.getPageSize() == 0) {
            totalPage = total / ao.getPageSize();
        } else {
            totalPage = total / ao.getPageSize() + 1;
        }

        CommonPage<OperateLogInfo> commonPage = new CommonPage();
        commonPage.setTotalPage((long) totalPage);
        commonPage.setTotalCount((long) total);
        commonPage.setPageSize((long) ao.getPageNo());
        commonPage.setPageSize((long) ao.getPageSize());
        commonPage.setList(list);
        return commonPage;
    }

    public Integer getTotal(OperateLogInfoGetPageListAO ao) {
        StringBuilder sql = new StringBuilder("select count(id) from `" + this.getTableName() + "` where 1=1 ");
        if (!com.mysql.cj.util.StringUtils.isNullOrEmpty(ao.getUserName())) {
            sql.append(" and user_name like concat('%','").append(ao.getUserName()).append("','%') ");
        }

        if (!com.mysql.cj.util.StringUtils.isNullOrEmpty(ao.getResource())) {
            sql.append(" and resource like concat('%','").append(ao.getResource()).append("','%') ");
        }

        if (!com.mysql.cj.util.StringUtils.isNullOrEmpty(ao.getOperTimeStart()) && !com.mysql.cj.util.StringUtils.isNullOrEmpty(ao.getOperTimeEnd())) {
            sql.append(" and add_time between '").append(ao.getOperTimeStart()).append("' and '").append(ao.getOperTimeEnd()).append("' ");
        }

        return (Integer) this.jdbcTemplate.queryForObject(sql.toString(), Integer.class);
    }
}

